package com.southsmart.sgeocserver.config;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.alibaba.druid.pool.DruidDataSource;
import com.southsmart.sgeocserver.exception.Asserts;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.sql.DriverManager;
import java.util.concurrent.ConcurrentHashMap;


/**
* 动态载入jdbc连接池
* @author cjunxian
* @date 2021/7/30
*/
@Component(value = JdbcDatasource.BEAN_NAME)
@ConfigurationProperties(prefix = "spring.datasource.druid")
@Setter
@Slf4j
public class JdbcDatasource extends DruidDataSource {

    public static final String BEAN_NAME = "JdbcDatasource";

    @Resource(name = SqlDBConfig.BEAN_NAME)
    SqlDBConfig sqlDBConfig;

    /**
     * 用来多个保存数据源
     */
    private static ConcurrentHashMap<String,DruidDataSource> datasources = new ConcurrentHashMap<>();

    /**
     * 启动时加载datasource
     */
    public void initDatasource(){
        if(CollUtil.isNotEmpty(sqlDBConfig.getDatasource())){
            for (SqlDB sqlDB : sqlDBConfig.getDatasource()) {
                this.getDatasource(sqlDB.getKey());
            }
        }else {
            Asserts.fail("数据源不能为空！");
        }
    }


    public DruidDataSource getDatasource(String key){

        if (datasources.containsKey(key)){
            return datasources.get(key);
        }

        //如果该数据源没有被初始化过
        SqlDB sqlDB = sqlDBConfig.getSqlDB(key);
        Asserts.isNull(sqlDB,"找不到该数据源！");
        //获取数据源配置参数
        String jdbcUrl = sqlDB.getUrl();
        String username = sqlDB.getUsername();
        String password = sqlDB.getPassword();
        DruidDataSource dataSource = new JdbcDatasource();
        String className = null;

        try {
            className = DriverManager.getDriver(jdbcUrl.trim()).getClass().getName();
        } catch (Exception e) {
            Asserts.fail("找不到该数据源驱动,原因："+e.getMessage());
        }
        if(CharSequenceUtil.isEmpty(className)){
            Asserts.fail("数据源："+key + "的驱动为空！");
        }
        //将配置文件中的参数写入到datasource中
        dataSource.setDriverClassName(className);
        dataSource.setUrl(jdbcUrl.trim());
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setInitialSize(initialSize);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxActive(maxActive);
        dataSource.setMaxWait(maxWait);
        dataSource.setTestOnBorrow(testOnBorrow);
        dataSource.setTestOnReturn(testOnReturn);
        dataSource.setPoolPreparedStatements(poolPreparedStatements);
        dataSource.setTestWhileIdle(testWhileIdle);
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        dataSource.setMaxOpenPreparedStatements(maxOpenPreparedStatements);
        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        dataSource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        dataSource.setValidationQuery(validationQuery);

        try {
            dataSource.init();
        } catch (Exception e) {
            log.error("数据源初始化失败,原因："+e.getMessage());
            Asserts.fail("数据源初始化失败！");
        }
        datasources.put(key,dataSource);
        return dataSource;
    }

    public void removeDatasource(String key) {
        if (datasources.containsKey(key)) {
            datasources.remove(key);
        }
    }


}
